package main

import (
	pb "fgo/advance/grpc/grpc-gateway/proto/hello" // 引入编译生成的包
	"fmt"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	//grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
	"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
	"github.com/opentracing/opentracing-go"
	zipkin "github.com/openzipkin-contrib/zipkin-go-opentracing"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
	"net"
	"os"
)

const (
	// Address gRPC服务地址
	Address = "127.0.0.1:50052"

	SERVICE_NAME = "simple_zipkin_server"
	// docker run -d -p 9411:9411 -p 9410:9410 openzipkin/zipkin
	ZIPKIN_HTTP_ENDPOINT      = "http://127.0.0.1:9411/api/v1/spans"
	ZIPKIN_RECORDER_HOST_PORT = "127.0.0.1:50051"
)

// 定义helloService并实现约定的接口
type helloService struct{}

// HelloService ...
var HelloService = helloService{}

func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	resp := new(pb.HelloReply)
	resp.Message = "Hello " + in.Name + "."

	return resp, nil
}

var tracer opentracing.Tracer

func init() {

	collector, err := zipkin.NewHTTPCollector(ZIPKIN_HTTP_ENDPOINT)
	if err != nil {
		fmt.Printf("unable to create Zipkin HTTP collector: %+v\n", err)
		os.Exit(-1)
	}
	// create recorder.
	recorder := zipkin.NewRecorder(collector, false, ZIPKIN_RECORDER_HOST_PORT, SERVICE_NAME)

	// create tracer.
	tracer, err = zipkin.NewTracer(
		recorder,
		zipkin.ClientServerSameSpan(true),
		zipkin.TraceID128Bit(true),
	)
	if err != nil {
		fmt.Printf("unable to create Zipkin tracer: %+v\n", err)
		os.Exit(-1)
	}

	// explicitly set our tracer to be the default tracer.
	// 第一种方式:
	// grpc.NewServer 添加中间件
	// otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads()),
	// 第二种方式
	// 使用 grpc_middleware
	// 1. 注册全局  Tracer
	// opentracing.InitGlobalTracer(tracer)
	// 2. grpc.NewServer 添加中间件
	// grpc_opentracing.UnaryServerInterceptor()
}

func main() {
	listen, err := net.Listen("tcp", Address)
	if err != nil {
		grpclog.Fatalf("failed to listen: %v", err)
	}
	// 实例化grpc Server
	s := grpc.NewServer(grpc_middleware.WithUnaryServerChain(
		otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads()),
	))

	// 注册HelloService
	pb.RegisterHelloServer(s, HelloService)

	grpclog.Info("Listen on " + Address)

	s.Serve(listen)
}
